from flask import Flask, render_template, request, jsonify, send_from_directory
from flask_socketio import SocketIO
import os
import base64
from utils import setup_logger, load_config, get_upload_dir, get_log_dir, get_temp_dir
from stream_manager import StreamManager
from wvp_media_manager import WvpMediaManager
import requests


app = Flask(__name__)
app.config["SECRET_KEY"] = "streaming_tool_secret"
socketio = SocketIO(app, async_mode="threading")

# 初始化
logger = setup_logger()
config = load_config()
stream_manager = StreamManager(socketio)
wvp_manager = WvpMediaManager(socketio)


@app.route("/")
def index():
    """导航首页"""
    return render_template("index.html")


@app.route("/stream_control")
def stream_control():
    """推拉流控制页面"""
    return render_template(
        "stream_control.html",
        config=config,
        protocols=config["push"].keys() if config else [],
    )


@app.route("/wvp_media_control")
def wvp_media_control():
    """WVP启停流控制页面"""
    return render_template("wvp_media_control.html")


@app.route("/start_stream", methods=["POST"])
def start_stream():
    """启动推流或拉流API"""
    if not request.json:
        return jsonify({"status": "error", "message": "无效的请求数据"}), 400

    data = request.json
    stream_type = data.get("stream_type")

    if stream_type not in ["push", "pull"]:
        return jsonify({"status": "error", "message": "无效的流类型"}), 400

    # 检查配置
    if not config:
        return jsonify({"status": "error", "message": "配置加载失败"}), 500

    # 检查是否已经在运行
    if stream_type == "push" and stream_manager.pushing:
        return jsonify({"status": "error", "message": "推流已经在运行"}), 400
    elif stream_type == "pull" and stream_manager.pulling:
        return jsonify({"status": "error", "message": "拉流已经在运行"}), 400

    # 验证必要参数
    if stream_type == "push" and not data.get("video_path"):
        return jsonify({"status": "error", "message": "请上传视频文件"}), 400

    if not data.get("server_address"):
        return jsonify({"status": "error", "message": "请填写服务器地址"}), 400

    # 启动流处理
    success, message = stream_manager.start_streaming(stream_type, data, config)
    if not success:
        return jsonify({"status": "error", "message": message}), 400

    return jsonify({"status": "success"})


@app.route("/stop_stream", methods=["POST"])
def stop_stream():
    """停止推流或拉流API"""
    if not request.json:
        return jsonify({"status": "error", "message": "无效的请求数据"}), 400

    data = request.json
    stream_type = data.get("stream_type")

    if stream_type not in ["push", "pull"]:
        return jsonify({"status": "error", "message": "无效的流类型"}), 400

    # 停止流处理
    stream_manager.stop_streaming(stream_type)

    # 创建唯一的停止消息
    stop_message = f"ALL {stream_type.upper()} STREAMS STOPPED"

    # 记录到本地日志
    logger.info(stop_message)

    # 返回响应
    return jsonify({"status": "success", "message": stop_message})


@app.route("/upload_video", methods=["POST"])
def upload_video():
    """上传视频文件"""
    try:
        if "file" not in request.files:
            return jsonify({"status": "error", "message": "没有文件部分"}), 400

        file = request.files["file"]
        if file.filename == "":
            return jsonify({"status": "error", "message": "未选择文件"}), 400

        # 创建上传目录
        upload_dir = get_upload_dir()
        if not os.path.exists(upload_dir):
            os.makedirs(upload_dir)

        filename = f"{file.filename}"
        file_path = os.path.join(upload_dir, filename)
        file.save(file_path)

        logger.info(f"app: 已上传视频文件: {filename} -> {file_path}")
        return jsonify(
            {"status": "success", "file_path": file_path, "filename": filename}
        )

    except Exception as e:
        logger.error(f"app: 文件上传失败: {str(e)}")
        return jsonify({"status": "error", "message": f"app: {str(e)}"}), 500


@app.route("/open_terminal", methods=["POST"])
def open_terminal():
    """打开终端"""
    try:
        if os.name == "nt":
            os.system("start cmd")
        else:
            os.system("x-terminal-emulator &")
        return jsonify({"status": "success", "message": "终端已打开"})
    except Exception as e:
        return jsonify({"status": "error", "message": f"打开终端失败: {str(e)}"}), 500


@app.route("/clear_temp", methods=["POST"])
def clear_temp():
    """清理临时文件"""
    try:
        temp_dir = get_temp_dir()
        if os.path.exists(temp_dir):
            for file in os.listdir(temp_dir):
                try:
                    os.remove(os.path.join(temp_dir, file))
                except:
                    pass
            logger.info("app: 临时文件已清理")
        return jsonify({"status": "success"})
    except Exception as e:
        return jsonify({"status": "error", "message": f"app: {str(e)}"}), 500


@app.route("/get_status", methods=["GET"])
def get_status():
    """获取当前状态"""
    return jsonify(
        {
            "pushing": stream_manager.pushing,
            "pulling": stream_manager.pulling,
            "push_count": len(stream_manager.push_processes),
            "pull_count": len(stream_manager.pull_processes),
        }
    )


# ================= WVP启停流API =================


@app.route("/get_wvp_token", methods=["GET"])
def get_wvp_token():
    domain = request.args.get("domain")
    username = request.args.get("username")
    password = request.args.get("password")

    if not domain or not username or not password:
        return jsonify({"status": "error", "message": "缺少参数"}), 400

    try:
        if not domain.endswith("/"):
            domain += "/"
        login_url = domain + "api/user/login"
        params = {"username": username, "password": password}
        response = requests.get(login_url, params=params)
        response.raise_for_status()

        data = response.json()
        token = data.get("data", {}).get("accessToken")
        if data.get("code") == 0 and token:
            return jsonify({"status": "success", "access_token": token})
        else:
            return (
                jsonify({"status": "error", "message": data.get("msg") or "登录失败"}),
                400,
            )
    except Exception as e:
        return jsonify({"status": "error", "message": f"获取Token失败: {str(e)}"}), 500


@app.route("/start_wvp_test", methods=["POST"])
def start_wvp_test():
    data = request.json
    if not data:
        return jsonify({"status": "error", "message": "无效的请求数据"}), 400

    domain = data.get("domain", "")

    # 启动测试
    success, message = wvp_manager.start_test(
        device_ids=data.get("device_ids", []),
        max_loops=data.get("max_loops", 100),
        access_token=data.get("access_token", ""),
        media_check_url=data.get("media_check_url", ""),
        check_interval=data.get("check_interval", 5),
        domain=domain,
    )

    if success:
        return jsonify({"status": "success", "message": message})
    else:
        return jsonify({"status": "error", "message": message}), 400


@app.route("/stop_wvp_test", methods=["POST"])
def stop_wvp_test():
    """停止WVP启停流测试"""
    wvp_manager.stop_test()
    return jsonify({"status": "success", "message": "WVP测试已停止"})


@app.route("/get_wvp_status", methods=["GET"])
def get_wvp_status():
    """获取WVP测试状态"""
    return jsonify(
        {
            "status": "success",
            "running": wvp_manager.running,
            "stats": {
                "totalLoops": wvp_manager.stats["total_loops"],
                "successCount": wvp_manager.stats["success_count"],
                "failureCount": wvp_manager.stats["failure_count"],
            },
        }
    )


# ================= Socket事件处理 =================


@socketio.on("connect")
def handle_connect():
    """客户端连接时发送当前状态"""
    socketio.emit(
        "status_update",
        {"pushing": stream_manager.pushing, "pulling": stream_manager.pulling},
    )
    socketio.emit(
        "wvp_status",
        {
            "running": wvp_manager.running,
            "stats": {
                "totalLoops": wvp_manager.stats["total_loops"],
                "successCount": wvp_manager.stats["success_count"],
                "failureCount": wvp_manager.stats["failure_count"],
            },
        },
    )


if __name__ == "__main__":
    # 创建必要的目录
    for dir_path in [get_upload_dir(), get_log_dir(), get_temp_dir()]:
        if not os.path.exists(dir_path):
            os.makedirs(dir_path)

    # 启动应用
    socketio.run(app, host="0.0.0.0", port=5000, debug=True, use_reloader=False)
